package com.m3958.firstgwt.server.module;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.naming.NamingException;
import javax.sql.DataSource;

import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Scopes;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import com.m3958.firstgwt.server.utils.PropsUtils;
import com.mchange.v2.c3p0.DataSources;
import com.mchange.v2.c3p0.jboss.C3P0PooledDataSource;

public class TcmsDataSourceModule extends AbstractModule{

	@Override
	protected void configure() {
		 Names.bindProperties(binder(), loadProperties());
		 bind(DataSource.class).annotatedWith(Names.named("tcmsds")).toProvider(C3p0DataSourceProvider.class).in(Scopes.SINGLETON);
	}
	
    private Properties loadProperties(){
        // Load properties from appropriate place...
        // should contain definitions for:
        // url=...
        // username=...
        // password=...
        try {
			return PropsUtils.load("tcmsjdbcnosvn.properties");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
    }

    static class C3p0DataSourceProvider implements Provider<DataSource> {

        private final String url;
        private final String username;
        private final String password;
        
        @Inject
        public C3p0DataSourceProvider(@Named("url") final String url,
                                    @Named("username") final String username,
                                    @Named("password") final String password) {
            this.url = url;
            this.username = username;
            this.password = password;
        }

        @Override
        public DataSource get() {
        	try {
				DataSource ds = DataSources.unpooledDataSource(url,username,password);
				return DataSources.pooledDataSource(ds);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			return null;
        }
    }

    static class MyService {
        private final DataSource dataSource;

        @Inject
        public MyService(final DataSource dataSource) {
            this.dataSource = dataSource;
        }

        public void singleUnitOfWork() {

            Connection cn = null;

            try {
                cn = dataSource.getConnection();
                // Use the connection
            } catch (SQLException e) {
				e.printStackTrace();
			} finally {
                try {
                    cn.close();
                } catch (Exception e) {}
            }
        }
    }
}
